﻿using System;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace DoodleLabyrinthLogic.Character
{
    public class Player : BaseCharacter
    {
        private const int XpPerLevelGain = 100;
        private readonly int _hitPointsGainedPerLevel;
        private readonly int _manaPointsGainedPerLevel;

        private readonly int _magicAttackGainedPerLevel;
        private readonly int _meleeAttackGainedPerLevel;

        private readonly int _magicDefenseGainedPerLevel;
        private readonly int _meleeDefenseGainedPerLevel;

        private readonly int _agilityGainedPerLevel;


        public Player(Guid id, string name, string description, int baseMeleeDefense, int baseMagicDefense, int baseAgility, int baseMeleeDamage, int baseMagicDamage, int baseHealth, int baseMmana, int level, int hitPointsGainedPerLevel, int manaPointsGainedPerLevel, int magicAttackGainedPerLevel, int meleeAttackGainedPerLevel, int magicDefenseGainedPerLevel, int meleeDefenseGainedPerLevel, int agilityGainedPerLevel, int currentXP) : base(id, name, description, baseMeleeDefense, baseMagicDefense, baseAgility, baseMeleeDamage, baseMagicDamage, baseHealth, baseMmana, level)
        {
            _hitPointsGainedPerLevel = hitPointsGainedPerLevel;
            _manaPointsGainedPerLevel = manaPointsGainedPerLevel;
            _magicAttackGainedPerLevel = magicAttackGainedPerLevel;
            _meleeAttackGainedPerLevel = meleeAttackGainedPerLevel;
            _magicDefenseGainedPerLevel = magicDefenseGainedPerLevel;
            _meleeDefenseGainedPerLevel = meleeDefenseGainedPerLevel;
            _agilityGainedPerLevel = agilityGainedPerLevel;
            _currentXP = currentXP;
        }

        public int CurrentLevel
        {
            get
            {
                return CurrentXP/XpPerLevelGain;
            }
        }

        private int _currentXP;
        public int CurrentXP
        {
            get
            {
                return _currentXP;
            }
        }

        public override int MeleeDamage
        {
            get
            {
                return base.MeleeDamage + (Level * _meleeAttackGainedPerLevel); 
            }
        }

        public override int MagicDamage
        {
            get
            {
                return base.MagicDamage + (Level * _magicAttackGainedPerLevel);
            }
        }

        public override int MeleeDefense
        {
            get
            {
                return base.MeleeDefense + (Level * _meleeDefenseGainedPerLevel);
            }
        }

        public override int MagicDefense
        {
            get
            {
                return base.MagicDefense + (Level * _magicDefenseGainedPerLevel);
            }
        }

        public override int Agility
        {
            get
            {
                return base.Agility + (Level * _agilityGainedPerLevel);
            }
        }

        public override int MaximumHealth
        {
            get
            {
                return base.MaximumHealth + (Level * _hitPointsGainedPerLevel);
            }
        }

        public override int MaximumMana
        {
            get
            {
                return base.MaximumMana + (Level * _manaPointsGainedPerLevel);
            }
        }

        public void AssignXP(BaseCharacter target)
        {
            int xpGain = 1;

            if(target.Level > Level)
            {
                xpGain = target.Level - Level;
            }

            _currentXP += xpGain;
        }

        public virtual XmlDocument ToXML()
        {
            StringBuilder stringBuilder = new StringBuilder();
            XmlWriter xmlWriter = XmlWriter.Create(stringBuilder);
            // Convert the object to XML data and put it in the stream
            XmlSerializer serializer = new XmlSerializer(typeof(Player));
            serializer.Serialize(xmlWriter, this);

            XmlDocument xmlDocument = new XmlDocument();

            xmlDocument.LoadXml(stringBuilder.ToString());

            return xmlDocument;
        }
    }
}
